#pragma once
#include <atomic>
#include <condition_variable>
#include <cstdint>
#include <jdbc/cppconn/connection.h>
#include <jdbc/cppconn/prepared_statement.h>
#include <jdbc/mysql_connection.h>
#include <jdbc/mysql_driver.h>
#include <memory>
#include <mutex>
#include <queue>
#include <thread>
class SqlConnect {
public:
  SqlConnect(sql::Connection *con, int64_t lastTime);
  std::unique_ptr<sql::Connection> _con;
  int64_t _last_oper_time;
};

class MysqlPool {
private:
  std::string _url;
  std::string _user;
  std::string _passwd;
  std::string _schema;
  int _poolSize;
  std::queue<std::unique_ptr<SqlConnect>> _pool;
  std::mutex _mutex;
  std::atomic<bool> _b_stop;
  std::thread _check_thread;
  std::condition_variable _cond;
  void checkConnection();

public:
  MysqlPool(const std::string &url, const std::string &user,
            const std::string &pass, const std::string &schema, int poolSize);
  std::unique_ptr<SqlConnect> getConnection();
  void returnConnect(std::unique_ptr<SqlConnect> con);
  void Close();
  ~MysqlPool();
};

struct UserInfo {
  std::string name;
  std::string pwd;
  int uid;
  std::string email;
};

class MysqlDao {
public:
  MysqlDao();
  ~MysqlDao();
  int RegUser(const std::string &name, const std::string &email,
              const std::string &pwd);
  bool CheckEmail(const std::string &email);
  bool UpdatePwd(const std::string &email, const std::string &newPwd);
  bool CheckPwd(const std::string &email, const std::string &pwd,
                UserInfo &userInfo);

private:
  std::unique_ptr<MysqlPool> _pool;
};